
#include "lvgl_main.h"
#include "lvgl.h"
#include "driver/platform_drm.h"



#define  DISP_BUF_SIZE    (LCD_W*LCD_H*4)

static lv_color_t disp_data_buf[DISP_BUF_SIZE];
static lv_disp_draw_buf_t lvgl_disp_buf;
static lv_disp_drv_t disp_drv;

static lv_indev_drv_t indev_drv_mouse;

static pthread_t  lvgl_refresh_thread;


int show_full_red(void)
{
	int i,j;

	for(j=0; j<buf.height; j++)
	{
		for(i = 0 ; i<buf.width;i++)
		{
			buf.vaddr[(j)*buf.width+(i)] = RED;
		}
	}
}


void drm_display_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
	int32_t i;
	int32_t j;

	int32_t x;
	int32_t y;
	int32_t area_w = 0;
	int32_t area_h = 0;

	uint32_t color_data = 0;

	lv_coord_t hres = disp_drv->hor_res;
	lv_coord_t vres = disp_drv->ver_res;


	/*Return if the area is out the screen*/
	if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {
		lv_disp_flush_ready(disp_drv);
		return;
	}
	
	area_w = area->x2 - area->x1 + 1;
	area_h = area->y2 - area->y1 + 1;

#if 0
	log_i("area_w=%d\n",area_w);
	log_i("area_h=%d\n",area_h);

	log_i("hres=%d\n",hres);
	log_i("vres=%d\n",vres);

	log_i("area->x1=%d\n",area->x1);
	log_i("area->x2=%d\n",area->x2);
	
	log_i("area->y1=%d\n",area->y1);
	log_i("area->y2=%d\n",area->y2);
#endif
	//******************************************************************************
	//drm show 

	for(i=0;i<buf.height;i++)
	{
		for(j=0;j<buf.width;j++)
		{
			if((i >= area->y1)&&(i <= (area->y2 ))&&(j >= area->x1)&&(j <= (area->x2)))
			{
				color_data = *((uint32_t*)(color_p));
				color_p++;
				buf.vaddr[(i)*buf.width+(j)] = color_data;
				
			}
		}
	}
	//******************************************************************************

	/*IMPORTANT! It must be called to tell the system the flush is ready*/
	lv_disp_flush_ready(disp_drv);

}

uint32_t custom_tick_get(void)
{
    static uint64_t start_ms = 0;
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}

void* lvgl_refresh_task(void *arg)
{
	while(1)
	{

		lv_timer_handler();
		usleep(1000);
	}
}

int lvgl_gui_init(void)
{
	int ret = -1;

	drm_init();

	/*LittlevGL init*/
    lv_init();	

	log_i("lvgl init succeed.\n");

	memset(disp_data_buf,0,DISP_BUF_SIZE);

    /*Initialize a descriptor for the buffer*/
    lv_disp_draw_buf_init(&lvgl_disp_buf, disp_data_buf, NULL, DISP_BUF_SIZE);

    /*Initialize and register a display driver*/
    lv_disp_drv_init(&disp_drv);
	
    disp_drv.draw_buf   = &lvgl_disp_buf;
    disp_drv.flush_cb   = drm_display_flush;
    disp_drv.hor_res    = LCD_W;
    disp_drv.ver_res    = LCD_H;
    lv_disp_drv_register(&disp_drv);	

	log_i("lvgl register disp succeed.\n");

#if 0
    lv_indev_drv_init(&indev_drv_mouse); /*Basic initialization*/
    indev_drv_mouse.type = LV_INDEV_TYPE_POINTER;

    /*This function will be called periodically (by the library) to get the mouse position and state*/
    indev_drv_mouse.read_cb = platform_mouse_read;
    lv_indev_t* mouse_indev = lv_indev_drv_register(&indev_drv_mouse);
#endif


#if 0
	/*Set a cursor for the mouse*/
	LV_IMG_DECLARE(mouse_cursor_icon); /*Declare the image file.*/
	lv_obj_t* cursor_obj = lv_img_create(lv_scr_act()); /*Create an image object for the cursor */
	lv_img_set_src(cursor_obj, &mouse_cursor_icon); 		  /*Set the image source*/
	lv_indev_set_cursor(mouse_indev, cursor_obj);			  /*Connect the image  object to the driver*/
#endif

	//******************************************************************************

	lv_obj_set_style_bg_opa(lv_scr_act(), LV_OPA_0, LV_PART_MAIN);
	//******************************************************************************

	desk_root_create();
	
	//******************************************************************************

	ret=pthread_create(&lvgl_refresh_thread,NULL,lvgl_refresh_task,NULL);
	if(ret != 0){
		log_e("thread error=%s\n",strerror(ret));
	}	
	//******************************************************************************


	//******************************************************************************
	
	return 0;
}
